<template>
  <div class="cesium-draw">
    <div id="cesium-drawer" />
    <canvas id="canvas-a" class="canvas" width="700" height="100"></canvas>
    <canvas id="canvas-b" class="canvas" width="700" height="100"></canvas>
    <div class="mouse-postion">{{ nowPostion.wgs84 }}</div>
  </div>
</template>

<script>
//参考：Cesium深入浅出之图层管理器 https://blog.csdn.net/fywindmoon/article/details/113747843
import { DownOutlined, EditOutlined } from '@ant-design/icons-vue';
import { defineComponent, ref, watch } from 'vue';
import * as Cesium from '@cesium/Source/Cesium.js';
import MousePosition from '@functional/utils/mousePosition';
import PrimitivePoints from './PrimitivePoints';
import { LonlatPointsTerrainData, CartographicPointsTerrainData } from './TerrainToolCopy';
import * as turf from '@turf/turf';

export default defineComponent({
  name: "calcVolumn",
  components: { DownOutlined, EditOutlined },
  setup() {
    return {
      viewer: null
    };
  },
  data() {
    return {
      nowPostion: {}
    };
  },
  computed: {},
  watch: {},
  mounted() {
    this.initViewer();
  },
  beforeUnmount() {
    if (this.viewer) {
      this.viewer.destroy();
      this.viewer = null;
    }
  },
  methods: {
    onViewerInited(viewer) {
      let vm = this;
      new MousePosition(viewer, pos => {
        vm.nowPostion = pos;
      });
    },

    initViewer() {
      let vm = this;
      Cesium.Ion.defaultAccessToken = $accessToken.default;
      // let terrainProvider = new Cesium.CesiumTerrainProvider({
      //   url: '//zzgis.com/cdn/3d/data/Terrain/beijing/'
      // });
      var terrainProvider = Cesium.createWorldTerrain();
      var viewer = new Cesium.Viewer('cesium-drawer', {
        // imageryProvider: osm,
        contextOptions: {
          webgl: {
            alpha: true
          }
        },
        animation: false,
        // baseLayerPicker: false,
        fullscreenButton: false,
        vrButton: false,
        homeButton: false,
        timeline: false,
        imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
          // url: '//services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer',
          url: '//services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
        }),
        selectionIndicator: false,
        infoBox: false,
        // 注释时相当于使用默认地形，解开注释相当于使用全球地形
        terrainProvider,
        shouldAnimate: true //动画播放
      });

      //开启深度检测
      // viewer.scene.globe.depthTestAgainstTerrain = true;

      this.viewer = viewer;
      this.onViewerInited(viewer);

      this.initEffects(terrainProvider);

      this.viewer.flyTo(this.viewer.entities);
    },
    initEffects(terrainProvider) {
      const viewer = this.viewer;

      //取消双击事件
      viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
      //设置homebutton的位置
      Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(116.15, 40.54, 116.25, 40.56); //Rectangle(west, south, east, north)
      //设置初始位置
      viewer.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(115.970076, 39.910064, 3000)
      });

      //开启深度检测
      //viewer.scene.globe.depthTestAgainstTerrain = true;

      let coordinates = [
        [
          [115.94282, 39.918712],
          [115.970076, 39.910064],
          [115.954399, 39.882855],
          [115.905748, 39.886989],
          [115.913215, 39.916541],
          [115.913217, 39.916543],
          [115.913225, 39.916551],
          [115.94282, 39.918712]
        ]
      ];

      // let tdpolygon = new Cesium.PolygonGeometry({
      //     vertexFormat: Cesium.PolylineColorAppearance.VERTEX_FORMAT,
      //     polygonHierarchy: new Cesium.PolygonHierarchy(
      //         Cesium.Cartesian3.fromDegreesArray([
      //             115.94282, 39.918712,
      //             115.970076, 39.910064,
      //             115.954399, 39.882855,
      //             115.905748, 39.886989,
      //             115.913215, 39.916541,
      //             115.913217, 39.916543,
      //             115.913225, 39.916551
      //         ])
      //     ),
      //     extrudedHeight: 0
      // });
      // let polygoninstance = new Cesium.GeometryInstance({
      //     geometry: tdpolygon,
      //     attributes: {
      //         color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromRandom({ alpha: 1 }))
      //     }
      // });
      // viewer.scene.primitives.add(new Cesium.Primitive({
      //     geometryInstances: [polygoninstance],
      //     appearance: new Cesium.PolylineColorAppearance({
      //         translucent: false
      //     })
      // }));

      let polygon = turf.polygon(coordinates);

      let area = turf.area(polygon);

      let cellsize = Math.sqrt(turf.area(polygon) / 10000);

      let enveloped = turf.envelope(polygon);

      let centroid = turf.centroid(polygon);

      let bbox = turf.bbox(enveloped);

      let grid = turf.pointGrid(bbox, cellsize, { units: 'meters' });

      let ptsWithin = turf.pointsWithinPolygon(grid, polygon);

      let lonlats = [];

      let features = ptsWithin.features;
      for (let i = 0; i < features.length; i++) {
        lonlats.push({
          lon: features[i].geometry.coordinates[0],
          lat: features[i].geometry.coordinates[1]
        });
      }

      setTimeout(() => {
        LonlatPointsTerrainData(terrainProvider, lonlats, positions => {
          getVolumn(positions);
        });
      }, 5000);

      function getVolumn(data) {
        let minHeight = findMinHeight(data);
        let maxHeight = findMaxHeight(data);
        let volumn = 0;
        let points = [];
        let colors = [];

        for (let i = 0; i < data.length; i++) {
          volumn += (data[i]['height'] - minHeight) * cellsize * cellsize;
          let point = Cesium.Cartesian3.fromRadians(data[i].longitude, data[i].latitude, data[i].height);
          points.push(point);
          colors.push(0);
          colors.push(0);
          colors.push(1);
          colors.push(1);
        }

        const primitivePoints = new PrimitivePoints(viewer, { viewer: viewer, Cartesians: points, Colors: colors });

        const primitive = viewer.entities.add(primitivePoints.create())

        viewer.entities.add({
          name: '标注',
          position: Cesium.Cartesian3.fromDegrees(centroid.geometry.coordinates[0], centroid.geometry.coordinates[1], maxHeight),
          label: {
            text: volumn + '立方米',
            font: '24px sans-serif',
            fillColor: Cesium.Color.WHITE,
            style: Cesium.LabelStyle.FILL_AND_OUTLINE,
            horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
            pixelOffset: new Cesium.Cartesian2(0.0, -70)
          }
        });

        viewer.flyTo(viewer.entities);
      }

      function findMinHeight(e) {
        let minHeight = 5000000;
        let minPoint = null;
        for (let i = 0; i < e.length; i++) {
          let height = e[i]['height'];
          if (height < minHeight) {
            minHeight = height;
          }
        }
        return minHeight;
      }
      function findMaxHeight(e) {
        let maxHeight = 0;
        let minPoint = null;
        for (let i = 0; i < e.length; i++) {
          let height = e[i]['height'];
          if (height > maxHeight) {
            maxHeight = height;
          }
        }
        return maxHeight;
      }
    }
  }
});
</script>

<style scoped lang="less">
.cesium-draw {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  color: white;
  font-size: 14px;

  #cesium-drawer {
    width: 100%;
    height: 100%;
    overflow: hidden;
    :deep(.cesium-viewer-bottom) {
      display: none !important;
    }
  }

  .mouse-postion {
    position: absolute;
    bottom: 10px;
    right: 10px;
    font-size: 14px;
    padding: 8px 12px;
    line-height: 16px;
    color: white;
    z-index: 9999;
    background-color: rgba(40, 48, 60, 1);
    border-radius: 3px;
    opacity: 0.8;
  }
}

.chart-container {
  position: absolute;
  bottom: 7px;
  left: 7px;
  background-color: rgba(0, 0, 0, 0.5);

  #profileChart {
    width: 600px;
    height: 300px;
  }
}
#canvas-a {
  top: 10px;
  display: none;
}

#canvas-b {
  top: 120px;
  display: none;
}
</style>
